package com.ss.SmartStock.controller.admin;

import com.ss.SmartStock.common.*;
import com.ss.SmartStock.exception.BusinessException;
import com.ss.SmartStock.exception.ThrowUtils;
import com.ss.SmartStock.manager.RedisLimiterManager;
import com.ss.SmartStock.pojo.entity.*;
import com.ss.SmartStock.redis.ProductManage;
import com.ss.SmartStock.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @author TsingFeng
 * @date 2024/6/17 17:10
 */
@Slf4j
@RestController
@Api(tags = "商品管理接口")
@RequestMapping("/admin/product")
public class ProductController {
    @Resource
    private ProductService productService;

    @Resource
    private ProductDetailsService productDetailsService;

    @Resource
    private UserService userService;

    @Resource
    private LogService logService;
    @Resource
    private OperationService operationService;

    @Resource
    RedisLimiterManager redisLimiterManager;
    @Resource
    private ProductManage productManage;

    /***
     * 根据id队列删除商品
     */
    @GetMapping("/delete/idList")
    @ApiOperation("根据id队列删除商品")
    @Transactional
    public BaseResponse<Boolean> deleteProductById(@RequestParam("idList") Collection<Long> idList, HttpServletRequest request) {
        log.info("根据id队列删除商品,id{}", idList);
        Log log = Log.builder()
                .userId(BaseContext.getCurrentId())
                .logLevel("INFO")
                .message("根据id队列删除商品")
                .build();
        logService.save(log);
        if (idList == null || idList.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 限流判断，每个用户一个限流器
        redisLimiterManager.doRateLimit("genChartByAi_" + BaseContext.getCurrentId());


        User user = userService.getLoginUser(request);

        Set<Long> pdidList = new HashSet<>();
        for (Long id : idList) {
            Product product = productService.getById(id);
            ThrowUtils.throwIf(product == null, ErrorCode.NOT_FOUND_ERROR);
            //仅本人或管理员可删除
            if (!product.getOperator().equals(user.getId()) && !userService.isAdmin(user)) {
                throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
            }
            Long productDetailsId = product.getProductDetailsId();

            pdidList.add(productDetailsId);
        }
        boolean flag = productService.removeByIds(idList);
        if (!flag)
            return ResultUtils.error(0, "删除商品基本信息失败");

        boolean flag1 = true;
        for (Long id : pdidList) {
            boolean b = productDetailsService.removeById(id);
            if (!b) {
                flag1 = false;
                break;
            }

        }
        if (!flag1)
            return ResultUtils.error(0, "删除商品详情信息失败");

        return ResultUtils.success(flag);
    }

    /**
     * 管理员上下线
     *
     * @param status
     * @param id
     * @return
     */

    @PostMapping("/status/{status}/{id}")
    @ApiOperation("上下线商品")
    public BaseResponse<Boolean> startOrStop(@PathVariable Integer status, @PathVariable Long id) {
        log.info("上下线商品id：{},{}", status, id);
        Log log = Log.builder()
                .userId(BaseContext.getCurrentId())
                .logLevel("INFO")
                .message("上下线商品")
                .build();
        logService.save(log);

        Product product = productService.getById(id);

        //管理员上线与强制下线
        product.setProductOnlineState(status);

        if (product != null) {
            Operation operation = Operation.builder()
                    .pDetailsId(id)
                    .status(status == 1 ? "上线" : "下线")
                    .operationTime(LocalDateTime.now())
                    .remarks("商品审核")
                    .operatorId(BaseContext.getCurrentId())
                    .build();
            operationService.insertOperation(operation);
        } else {
            return Result.error(ErrorCode.NOT_FOUND_ERROR);
        }
        return Result.success(productService.updateById(product));

    }

    /**
     * 审核商品
     *
     * @param id
     * @return
     */
    @PostMapping("/approval/{status}/{id}")
    @ApiOperation("审核商品")
    public BaseResponse<Boolean> approval(@PathVariable Integer status, @PathVariable Long id) {
        Long adminId = BaseContext.getCurrentId();

        //创建日志，持久化
        log.info("审核商品id: {}，审核员id：{}", id, adminId);
        Log log = Log.builder()
                .userId(adminId)
                .logLevel("INFO")
                .message("审核商品")
                .build();
        logService.save(log);

        //修改商品审核状态
        Product product = productService.getById(id);

        if (product != null) {
            Operation operation = Operation.builder()
                    .pDetailsId(id)
                    .status(product.getProductCheckState() == 1 ? "审核通过" : "审核不通过")
                    .operationTime(LocalDateTime.now())
                    .remarks("商品审核")
                    .operatorId(BaseContext.getCurrentId())
                    .build();
            operationService.insertOperation(operation);
        } else {
            return Result.error(ErrorCode.NOT_FOUND_ERROR);
        }

        product.setProductCheckState(status);//1:审核通过

        // 计算上线和下线时间（以秒为单位）
        ProductDetails productDetail = productDetailsService.getById(product.getProductDetailsId());
        LocalDateTime timeOn = productDetail.getTimeOn();
        LocalDateTime timeOff = productDetail.getTimeOff();
        // 计算两个日期时间之间的差值
        Duration durationOn = Duration.between(LocalDateTime.now(), timeOn);
        Duration durationOff = Duration.between(LocalDateTime.now(), timeOff);

        long delayOn = durationOn.getSeconds();
        long delayOff = durationOff.getSeconds();

        //上线
        productManage.storeProductIdOnline(product.getProductId().toString(), delayOn);
        //下线
        productManage.storeProductIdOffline(product.getProductId().toString(), delayOff);


        return Result.success(productService.updateById(product));
    }

}
